#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) #pragma warning disable using System; using System.Collections; using System.IO; using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters; using BestHTTP.SecureProtocol.Org.BouncyCastle.Security; using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.IO; namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Tls { public class TlsDheKeyExchange : TlsDHKeyExchange { protected TlsSignerCredentials mServerCredentials = null; [Obsolete("Use constructor that takes a TlsDHVerifier")] public TlsDheKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, DHParameters dhParameters) : this(keyExchange, supportedSignatureAlgorithms, new DefaultTlsDHVerifier(), dhParameters) { } public TlsDheKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, TlsDHVerifier dhVerifier, DHParameters dhParameters) : base(keyExchange, supportedSignatureAlgorithms, dhVerifier, dhParameters) { } public override void ProcessServerCredentials(TlsCredentials serverCredentials) { if (!(serverCredentials is TlsSignerCredentials)) throw new TlsFatalAlert(AlertDescription.internal_error); ProcessServerCertificate(serverCredentials.Certificate); this.mServerCredentials = (TlsSignerCredentials)serverCredentials; } public override byte[] GenerateServerKeyExchange() { if (this.mDHParameters == null) throw new TlsFatalAlert(AlertDescription.internal_error); DigestInputBuffer buf = new DigestInputBuffer(); this.mDHAgreePrivateKey = TlsDHUtilities.GenerateEphemeralServerKeyExchange(mContext.SecureRandom, this.mDHParameters, buf); /* * RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2 */ SignatureAndHashAlgorithm signatureAndHashAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm( mContext, mServerCredentials); IDigest d = TlsUtilities.CreateHash(signatureAndHashAlgorithm); SecurityParameters securityParameters = mContext.SecurityParameters; d.BlockUpdate(securityParameters.clientRandom, 0, securityParameters.clientRandom.Length); d.BlockUpdate(securityParameters.serverRandom, 0, securityParameters.serverRandom.Length); buf.UpdateDigest(d); byte[] hash = DigestUtilities.DoFinal(d); byte[] signature = mServerCredentials.GenerateCertificateSignature(hash); DigitallySigned signed_params = new DigitallySigned(signatureAndHashAlgorithm, signature); signed_params.Encode(buf); return buf.ToArray(); } public override void ProcessServerKeyExchange(Stream input) { SecurityParameters securityParameters = mContext.SecurityParameters; SignerInputBuffer buf = new SignerInputBuffer(); Stream teeIn = new TeeInputStream(input, buf); this.mDHParameters = TlsDHUtilities.ReceiveDHParameters(mDHVerifier, teeIn); this.mDHAgreePublicKey = new DHPublicKeyParameters(TlsDHUtilities.ReadDHParameter(teeIn), mDHParameters); DigitallySigned signed_params = ParseSignature(input); ISigner signer = InitVerifyer(mTlsSigner, signed_params.Algorithm, securityParameters); buf.UpdateSigner(signer); if (!signer.VerifySignature(signed_params.Signature)) throw new TlsFatalAlert(AlertDescription.decrypt_error); } protected virtual ISigner InitVerifyer(TlsSigner tlsSigner, SignatureAndHashAlgorithm algorithm, SecurityParameters securityParameters) { ISigner signer = tlsSigner.CreateVerifyer(algorithm, this.mServerPublicKey); signer.BlockUpdate(securityParameters.clientRandom, 0, securityParameters.clientRandom.Length); signer.BlockUpdate(securityParameters.serverRandom, 0, securityParameters.serverRandom.Length); return signer; } } } #pragma warning restore #endif